﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading;
using System.Windows.Forms;

namespace AutoUpdateGithubHost
{
    public partial class Form1 : Form
    {

        public Form1()
        {
            InitializeComponent();
        }

        public static string RunCmd(string cmd)
        {
            string CmdPath = @"C:\Windows\System32\cmd.exe";
            cmd = cmd.Trim().TrimEnd('&') + "&exit";//说明：不管命令是否成功均执行exit命令，否则当调用ReadToEnd()方法时，会处于假死状态
            using (Process p = new Process())
            {
                p.StartInfo.FileName = CmdPath;
                p.StartInfo.UseShellExecute = false;        //是否使用操作系统shell启动
                p.StartInfo.RedirectStandardInput = true;   //接受来自调用程序的输入信息
                p.StartInfo.RedirectStandardOutput = true;  //由调用程序获取输出信息
                p.StartInfo.RedirectStandardError = true;   //重定向标准错误输出
                p.StartInfo.CreateNoWindow = true;          //不显示程序窗口
                p.Start();//启动程序

                //向cmd窗口写入命令
                p.StandardInput.WriteLine(cmd);
                p.StandardInput.AutoFlush = true;

                //获取cmd窗口的输出信息
                string output = p.StandardOutput.ReadToEnd();
                p.WaitForExit();//等待程序执行完退出进程
                p.Close();
                return output;
            }
        }

        public static string HttpDownloadFile(string url, string path)
        {
            //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);

            System.Net.ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;
            // 设置参数
            HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
            //发送请求并获取相应回应数据
            HttpWebResponse response = request.GetResponse() as HttpWebResponse;
            //直到request.GetResponse()程序才开始向目标网页发送Post请求
            Stream responseStream = response.GetResponseStream();

            //创建本地文件写入流
            Stream stream = new FileStream(path, FileMode.Create);

            byte[] bArr = new byte[1024];
            int size = responseStream.Read(bArr, 0, (int)bArr.Length);
            while (size > 0)
            {
                stream.Write(bArr, 0, size);
                size = responseStream.Read(bArr, 0, (int)bArr.Length);
            }
            stream.Close();
            responseStream.Close();
            return path;
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            new Thread(Update).Start();
        }

        void addmsg(string msg)
        {
            BeginInvoke(new Action(() => {
                listBox1.Items.Add(msg);
            }));
        }

        void Update()
        {
            string host_path = @"C:\Windows\System32\drivers\etc\hosts";
            string gitHostFileLink = "https://hub.fastgit.org/ButterAndButterfly/GithubHost/releases/download/v1/host.txt";
            string downloadpath = "host.txt";
            addmsg("download:" + gitHostFileLink);
            HttpDownloadFile(gitHostFileLink, downloadpath);
            if (File.Exists(downloadpath))
            {
                string[] lines = File.ReadAllLines(downloadpath);
                if (lines.Length < 4)
                {
                    addmsg("download failed?");
                    return;
                }
                addmsg("replace host content");
                var hostlines = File.ReadAllLines(host_path).ToList();

                int start = hostlines.IndexOf("# GitHub Start");
                int end = hostlines.IndexOf("# GitHub End");
                if (start != -1 && end != -1)
                {
                    for (int i = end; i >= start; i--)
                    {
                        hostlines.RemoveAt(i);
                    }
                    for (int i = 0; i < lines.Length; i++)
                    {
                        hostlines.Insert(start + i, lines[i]);
                    }
                }
                else
                {

                    for (int i = 0; i < lines.Length; i++)
                    {
                        hostlines.Add(lines[i]);
                    }
                }

                StringBuilder sb = new StringBuilder();
                foreach (var item in hostlines)
                {
                    sb.AppendLine(item);
                }
                var hostctx = sb.ToString();
                addmsg("replace host file");
                File.WriteAllText(host_path, hostctx);
                string output = RunCmd("ipconfig /flushdns");
                var outputs = output.Split(new char[] { '\n', '\r' });
                foreach (var item in outputs)
                {
                    if (item!="")
                    {
                        addmsg(item);
                    }
                }
            }
        }
    }
}
